#include "stm32l496xx.h"
#include "main.h"
#include <stdint.h>
#include "DELAY.h"
#include "I2C.h"


void I2C_AN_SDA_OUT(void)
{
	HAL_GPIO_DeInit(GPIOC,GPIO_PIN_0);
	
	__HAL_RCC_GPIOC_CLK_ENABLE();
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void I2C_AN_SDA_IN(void)
{
	HAL_GPIO_DeInit(GPIOC,GPIO_PIN_0);
	
	__HAL_RCC_GPIOC_CLK_ENABLE();
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void I2C_AN_Start(void)
{
	I2C_AN_SDA_OUT();
	Set_I2C_SDA;	  	  
	Set_I2C_SCL;
	delay_us(4);
 	Reset_I2C_SDA;
	delay_us(4);
	Reset_I2C_SCL;
}

void I2C_AN_Stop(void)
{
	I2C_AN_SDA_OUT();
	Reset_I2C_SCL;
	Reset_I2C_SDA;
 	delay_us(4);
	Set_I2C_SCL; 
	Set_I2C_SDA;
	delay_us(4);							   	
}

uint8_t I2C_AN_Wait_Ack(void)
{
	uint8_t ucErrTime=0;	
	Set_I2C_SDA;
	I2C_AN_SDA_IN();	 	
	delay_us(1);	   
	Set_I2C_SCL;
	delay_us(1);			
	while(I2C_READ_SDA)
	{
		ucErrTime++;
		delay_us(1);
		if(ucErrTime>250)
		{
			I2C_AN_Stop();
			return 1;
		}
	}
	Reset_I2C_SCL;	   
	return 0;  
} 

void I2C_AN_Ack(void)
{
	Reset_I2C_SCL;
	I2C_AN_SDA_OUT();
	Reset_I2C_SDA;
	delay_us(2);
	Set_I2C_SCL;
	delay_us(2);
	Reset_I2C_SCL;
}

void I2C_AN_No_Ack(void)
{
	Reset_I2C_SCL;
	I2C_AN_SDA_OUT();
	Set_I2C_SDA;
	delay_us(2);
	Set_I2C_SCL;
	delay_us(2);
	Reset_I2C_SCL;
}

void I2C_AN_Send_Byte(uint8_t txd)
{                        
  uint8_t t;   
  I2C_AN_SDA_OUT(); 	    
  Reset_I2C_SCL;//数据开始传输的时候需要拉低时钟线
  for(t=0;t<8;t++)
  {              
		if((txd&0x80)>>7)
		{
			Set_I2C_SDA;
		}
		else
		{
			Reset_I2C_SDA;
		}
    txd=txd<<1; 
		delay_us(2);   // 不同的器件有不同的要求，根据要求进行配置
		Set_I2C_SCL;
		delay_us(2); 
		Reset_I2C_SCL;	
		delay_us(2);
  }	 
} 

uint8_t I2C_AN_Read_Byte(void)
{
	unsigned char i,receive=0;
	I2C_AN_SDA_IN();
  for(i=0;i<8;i++ )
	{
    Reset_I2C_SCL; 
    delay_us(2);
		Set_I2C_SCL;
    receive<<=1;
    if(I2C_READ_SDA) receive|=0x01;   
		delay_us(1); 
  }					 
  return receive;
}

uint8_t I2C_AN_Slave_Ack(uint8_t slave_add)
{
	uint8_t dat=0;
	I2C_AN_Start();  
	I2C_AN_Send_Byte(slave_add);  
	dat=I2C_AN_Wait_Ack();
	I2C_AN_Stop(); 	
	return dat;	
}

void 	WriteOneByte(uint8_t DeviceAdd,uint8_t PointAddr,uint8_t DataToWrite)
{				
	I2C_AN_Start();  
	I2C_AN_Send_Byte(DeviceAdd);   	 
	I2C_AN_Wait_Ack();	   
	I2C_AN_Send_Byte(PointAddr);   
	I2C_AN_Wait_Ack();
	Set_I2C_SDA;
	I2C_AN_Send_Byte(DataToWrite);
	I2C_AN_Wait_Ack();
	I2C_AN_Stop(); 
	delay_ms(30);	 
}

void 	WriteOneWord(uint8_t DeviceAdd,uint8_t PointAddr,uint16_t DataToWrite)
{					
	I2C_AN_Start();  
	I2C_AN_Send_Byte(DeviceAdd);    
	I2C_AN_Wait_Ack();	   
	I2C_AN_Send_Byte(PointAddr);   
	I2C_AN_Wait_Ack();
	Set_I2C_SDA;
	I2C_AN_Send_Byte((DataToWrite>>8)&0xff);
	I2C_AN_Wait_Ack();
	I2C_AN_Send_Byte(DataToWrite&0xff);
	I2C_AN_Wait_Ack(); 
	I2C_AN_Stop();
	delay_ms(30);	 
} 

uint8_t ReadOneByte(uint8_t DeviceAdd, uint8_t PointAddr)
{
	uint8_t temp=0;
	I2C_AN_Start();  
	I2C_AN_Send_Byte(DeviceAdd);   
	I2C_AN_Wait_Ack();
	I2C_AN_Send_Byte(PointAddr);
	I2C_AN_Wait_Ack();
	I2C_AN_Start();
	I2C_AN_Send_Byte(DeviceAdd|0x01);
	I2C_AN_Wait_Ack();    
	temp=I2C_AN_Read_Byte();
	I2C_AN_Stop();
	return temp;
}

uint16_t ReadOneWord(uint8_t DeviceAdd, uint8_t PointAddr)
{				  
	uint8_t tempH=0;
	uint8_t tempL=0;
	uint16_t temp=0;
	I2C_AN_Start();  
	I2C_AN_Send_Byte(DeviceAdd);   
	I2C_AN_Wait_Ack();
	I2C_AN_Send_Byte(PointAddr); 
	I2C_AN_Wait_Ack();
 
	I2C_AN_Start();
	I2C_AN_Send_Byte(DeviceAdd|0x01);  
	I2C_AN_Wait_Ack();    
	tempH=I2C_AN_Read_Byte();
	I2C_AN_Ack();
	Set_I2C_SDA;    
	tempL=I2C_AN_Read_Byte();
	I2C_AN_No_Ack();
	I2C_AN_Stop();
	temp = (tempH << 8) | tempL ;
	return temp;
}


